﻿using System;
using System.IO;
using System.Collections.Concurrent;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;


namespace WpfApp.Models
{
    [Description("爬虫")]
    internal class Crawler
    {
        public Hashtable urls = new Hashtable();
        public List<string> urlsList = new List<string>();
        public static List<string> errorList = new List<string>();
        public static ConcurrentBag<string> visitedUrls = new ConcurrentBag<string>();
        public static ConcurrentDictionary<string, string> definitionsWithUrls = new ConcurrentDictionary<string, string>();
        private static readonly string logFilePath = "crawler_log.txt";

        public static void ClearData()
        {
            visitedUrls = new ConcurrentBag<string>();
            definitionsWithUrls = new ConcurrentDictionary<string, string>();
            errorList = new List<string>();
        }

        public static async Task ExtractDefinitions(string url)
        {
            if (!visitedUrls.Contains(url))
            {
                visitedUrls.Add(url);
                Log("正在访问：" + url);
                string html = await DownloadHtml(url);
                if (html != null)
                {
                    var definitions = ParseDefinitions(html);
                    foreach (var definition in definitions)
                    {
                        if (!definitionsWithUrls.ContainsKey(definition.Key))
                        {
                            definitionsWithUrls.TryAdd(definition.Key, definition.Value);
                            Log("找到释义：" + definition.Value + "，所属的 URL：" + url);
                        }
                    }
                }
            }
        }

        static async Task<string> DownloadHtml(string url)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
                    client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
                    client.DefaultRequestHeaders.Add("Accept-Language", "en-US,en;q=0.5");
                    client.DefaultRequestHeaders.Add("Connection", "keep-alive");
                    client.DefaultRequestHeaders.Add("Upgrade-Insecure-Requests", "1");

                    HttpResponseMessage response = await client.GetAsync(url);
                    response.EnsureSuccessStatusCode();
                    string html = await response.Content.ReadAsStringAsync();
                    return html;
                }
            }
            catch (HttpRequestException ex)
            {
                Log("访问 URL " + url + " 失败，错误信息：" + ex.Message);
                errorList.Add("访问 URL " + url + " 失败，错误信息：" + ex.Message);
                return null;
            }
        }

        static Dictionary<string, string> ParseDefinitions(string html)
        {
            var definitions = new Dictionary<string, string>();
            var doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);

            // 查找包含词性和释义的节点
            var nodes = doc.DocumentNode.SelectNodes("//ul[@class='basic']/li[@class='word-exp']");
            if (nodes != null)
            {
                foreach (var node in nodes)
                {
                    var posNode = node.SelectSingleNode(".//span[@class='pos']");
                    var transNode = node.SelectSingleNode(".//span[@class='trans']");
                    if (posNode != null && transNode != null)
                    {
                        string pos = posNode.InnerText.Trim();
                        string trans = transNode.InnerText.Trim();
                        definitions.Add(pos, trans);
                    }
                }
            }

            return definitions;
        }

        static void Log(string message)
        {
            Console.WriteLine(message);
            errorList.Add(message);
            File.AppendAllText(logFilePath, $"{DateTime.Now}: {message}{Environment.NewLine}");
        }
    
    }
}
